<template>
  <div id="swiper">
    <div class="swiper" @touchstart="touch_start($event)" @touchmove="touch_move($event)" @touchend="touch_end($event)" ref="swiper">
      <slot></slot>
    </div>
    <!-- 图片底部小圆点 -->
    <div  class="indicator">
      <slot name="indicator">
        <div
          v-for="(item, index) in slideCount"
          class="indi-item"
          :key="index"
          :class="{active: index === currentIndex - 1 }"
        ></div>
      </slot>
    </div>
  </div>
</template>

<script>
export default {
  name: "Swiper",
  data() {
    return {
      interval: 3000,
      animDuration: 300,
      moveRatio: 0.25,
      ShowIndicator: true,
      slideCount: 0, // 元素个数
      totalWidth: 0, // swiper的宽度
      swiperStyle: {}, // swiper样式
      currentIndex: 1, // 当前的index
      scrolling: false // 是否正在滚动
    };
  },
  mounted() {
    // 1.操作dom，在前后添加slide
    setTimeout(() => {
      this.handleDom();
      // 2.开启定时器
      this.startTimer();
    }, 100);
  },
  methods: {
    // 定时器
    startTimer() {
      this.playTimer = window.setInterval(() => {
        this.currentIndex++;
        this.scrollContent(-this.currentIndex * this.totalWidth);
      }, this.interval);
    },
    stopTimer() {
      window.clearInterval(this.playTimer);
    },

    // 滚动到正确位置
    scrollContent(currentPosition) {
      // 1.设置正在滚动
      this.scrolling = true;

      // 2.开始滚动动画
      this.swiperStyle.transition =  this.animDuration + "ms";
      
      this.setTransform(currentPosition);

      // 3.判断滚动到的位置
      this.checkPosition();

      // 4.滚动完成
      this.scrolling = false;
    },
    //校验正确的位置
    checkPosition() {
      window.setTimeout(() => {
        this.swiperStyle.transition = "0ms";
        if (this.currentIndex >= this.slideCount + 1) {
          this.currentIndex = 1;
          this.setTransform(-this.currentIndex * this.totalWidth);
        } else if (this.currentIndex <= 0) {
          this.currentIndex = this.slideCount;
          this.setTransform(-this.currentIndex * this.totalWidth);
        }
        // 2.结束移动后的回调
        this.$emit("transitionEnd", this.currentIndex - 1);
      }, this.animDuration);
    },

    //设置滚动的位置
    setTransform(position) {
      this.swiperStyle.transform = `translate3d(${position}px, 0, 0)`;
      this.swiperStyle[
        "-webkit-transform"
      ] = `translate3d(${position}px), 0, 0`;
      this.swiperStyle["-ms-transform"] = `translate3d(${position}px, 0, 0)`;
    },

    //操作dom，在前后添加slide
    handleDom(){
      // 1、获取需要操作的元素
      let swiperEl = document.querySelector('.swiper');
     
      let slidesEls = swiperEl.getElementsByClassName('slide');

      // 2、保存个数
      this.slideCount = slidesEls.length;

      // 3、如果大于一个，在前后分别添加一个slide
      if(this.slideCount > 1){
        let cloneFirst = slidesEls[0].cloneNode(true);
        let cloneLast = slidesEls[this.slideCount -1].cloneNode(true);
        swiperEl.insertBefore(cloneLast,slidesEls[0]);
        swiperEl.appendChild(cloneFirst);
        this.totalWidth = swiperEl.offsetWidth;
        this.swiperStyle = swiperEl.style;
      }
            // 4、让swiper显示第一个
      this.setTransform(-this.totalWidth);
    },

    //拖动事件处理
    touch_start(e){
      // 1、如果正在滚动，不可以拖动
      if(this.scrolling) return;
      // 2、停止定时器
      this.stopTimer();
      // 3、保存开始滚动的位置
      this.startX = e.touches[0].pageX;
    },

    touch_move(e){
      // 1、计算出用户拖动的距离
      this.currentX = e.touches[0].pageX;
      this.distance = this.currentX - this.startX;
      let currentPosition = -this.currentIndex * this.totalWidth;
      let moveDistance = this.distance + currentPosition;
      // 2、设置当前的位置
      this.setTransform(moveDistance);
    },

    touch_end(e){
      // 1、获取移动的距离
      let currentMove = Math.abs(this.distance);
      // 2、判断最终的距离
      if(this.distance ===0){
        return
      } else if(this.distance > 0 && currentMove > this.totalWidth * this.moveRatio){
        this.currentIndex--
      }else if(this.distance < 0 && currentMove > this.totalWidth * this.moveRatio){
        this.currentIndex++
      }
      // 3、移动到正确位置
      this.scrollContent( -this.currentIndex * this.totalWidth);
      // 4、移动完成后重新开启定时器
      this.startTimer();
    }
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  #swiper {
    /* overflow: hidden; */
    position: relative;
  }

  .swiper {
    display: flex;
  }

  .indicator {
    display: flex;
    justify-content: center;
    position: absolute;
    width: 100%;
    bottom: 8px;
  }

  .indi-item {
    box-sizing: border-box;
    width: 10px;
    height: 10px;
    border-radius: 5px;
    background-color: #fff;
    border: .5px solid #333;
    line-height: 8px;
    text-align: center;
    font-size: 12px;
    margin: 0 5px;
  }
  .indi-item.active{
    background-color:  rgba(212,62,46,1.0);;
  }
</style>
